package cn.com.cennavi.bean;

import java.io.IOException;

import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.io.ParseException;
import com.vividsolutions.jts.io.WKTReader;
import java.io.Serializable;

/**
 * 一个分歧点道路单方向上所有的地图信息
 * 
 * @ClassName: DifPointTotalMapInfo
 * @Description: TODO（这里用一句话描述这个类的作用）
 * @author bull
 * @date 2016年4月14日 下午1:59:35
 *
 */
public class DifPointTotalMapInfo implements Serializable {

	private static final long serialVersionUID = 1L;

	/**
	 * 字段定义，各字段以逗号隔开 : 静态属性值： 1.路径ID 2.link序列 3.各Link距序列起点的距离 4.序列总长度
	 * 5.分歧点距序列起点距离 6.进入分歧点Link|出分歧点Link
	 * 7.分歧点ID，8.分歧点经度，9.分歧点纬度,10.分歧点link与正北方向的夹角（进出口标志位为0、1取分歧点后的link，
	 * 标志位为2的取分歧点之前的link），11.进出匝道口标志位（0: 沿原道路继续行驶，1:出匝道，2:匝道汇入）
	 **/
	public String roadId;
	/**
	 * link序列
	 */
	public String linkArr;
	/**
	 * link序列距离起始link的距离（米）
	 */
	public String LinkDisArr;
	/**
	 * link序列总长度（米）
	 */
	public int totalLength;
	/**
	 * 分歧点距离起始link的距离
	 */
	public int dif_Point_Dis;
	/**
	 * 进入分歧点和出分歧点的link
	 */
	public String enter_out_DifPoint_Link;
	/**
	 * 分歧点道路id
	 */
	public String dif_Point_Id;
	/**
	 * 经度
	 */
	public double dif_lon;
	/**
	 * 纬度
	 */
	public double dif_lat;
	/**
	 * 通行角度（正北方向夹角）
	 */
	public double difPoint_angle;
	/**
	 * 分岔口道路直行方向的角度（正北方向夹角）
	 */
	public double straight_angle;
	/**
	 * 当方向通行标志：0:沿原道路继续行驶，1:出匝道，2:匝道汇入3:掉头4: 左转5: 右转
	 */
	public int flag;
	// 所属分歧点的形状：（封闭道路用：）00、01、10、11，00表示左出，10表示右出，01表示左入，11表示右入，（地面道路用：）02表示掉头,20表示直行，30表示左转，03表示右转

	/**
	 * （封闭道路用：）00、01、10、11，00表示左出，10表示右出，01表示左入，11表示右入，（地面道路用：）02表示地面道路（只有左转），20
	 * 表示地面道路（只有右转），03表示地面道路（既有左转又有右转）
	 */
	public String dir;
	/**
	 * 分歧点距离末尾link的长度
	 */
	public int difPoint_startDis;
	/**
	 * 整条道路的缓冲区形状
	 */
	public Geometry roadGeo;
	/**
	 * 整条道路上每条link的长度信息
	 */
	public String linksLen;
	/**
	 * 整条道路所属的meshid（100m*100m的网格）
	 */
	public String meshIdSeq;
	/**
	 * 对于单方向上有多条道路的，记录最后相同的linkid，分歧点后的最后一个相同的link
	 */
	public String lastSameLink;
	/**
	 * 对于单方向上有多条道路的，记录第一个相同的linkid，分歧点前的第一个相同的link
	 */
	public String firstSameLink;
	/**
	 * 距离最后link有效的长度范围-最小值
	 */
	public int minSuitableDisFromLastLink;
	/**
	 * 距离最后link有效的长度范围-最大值
	 */
	public int maxSuitableDisFromLastLink;
	/**
	 * 出现分叉情况时，公共link开始位置距离末尾link的距离，末尾是指时间顺序最后位置
	 * maxSuitableDisFromLastLink-minSuitableDisFromLastLink
	 * 
	 * @param closeRoadMapData
	 */
	public int samelinkLen;
	/**
	 * 分歧点距离单方向公共路段末尾的距离
	 */
	public int difPointFromSamelinkLen;
	/**
	 * 道路行驶方向刚进入的方位角（-180--180）
	 */
	public double enter_Azimuth;
	/**
	 * 道路行驶方向最后输出的方位角（-180--180）
	 */
	public double out_Azimuth;
	/**
	 * 道路类型：0：封闭道路，1：地面道路
	 */
	public int roadClass;
	/**
	 * 车道序列号，代表该条道路那几个车道
	 * 
	 * @param closeRoadMapData
	 * @param roadClass
	 */
	public String inlaneNoSeq;
	/**
	 * 车道序列号，代表该条道路那几个车道
	 * 
	 * @param closeRoadMapData
	 * @param roadClass
	 */
	public String outlaneNoSeq;
	/**
	 * 车道序列号，代表该条道路那几个车道
	 * 
	 * @param closeRoadMapData
	 * @param roadClass
	 */
	public int inlinkNum;
	/**
	 * 车道序列号，代表该条道路那几个车道
	 * 
	 * @param closeRoadMapData
	 * @param roadClass
	 */
	public int outlinkNum;
	/**
	 * 进车道转向序列
	 */
	public String inlaneTurnFlag;
	/**
	 * 出车道转向序列
	 */
	public String outlaneTurnFlag;
	

	public DifPointTotalMapInfo(CloseRoadMapData closeRoadMapData, int roadClass) {
		// TODO Auto-generated constructor stub

		this.roadId = closeRoadMapData.roadId;
		this.linkArr = closeRoadMapData.linkseq;
		this.dif_Point_Id = closeRoadMapData.nodeId;
		this.enter_out_DifPoint_Link = closeRoadMapData.inRoadId + "|" + closeRoadMapData.outRoadId;
		this.LinkDisArr = closeRoadMapData.disSeq;
		this.straight_angle = closeRoadMapData.angel;
		this.flag = closeRoadMapData.flag;
		this.dif_lon = closeRoadMapData.lon;
		this.dif_lat = closeRoadMapData.lat;
		this.totalLength = closeRoadMapData.totalLen;
		this.roadClass = roadClass;

	}

	public DifPointTotalMapInfo() {
		// TODO Auto-generated constructor stub
	}

	public String toString() {
		StringBuffer sb = new StringBuffer();
		sb.append(this.roadId);
		sb.append(",");
		sb.append(this.linkArr);
		sb.append(",");
		sb.append(this.LinkDisArr);
		sb.append(",");
		sb.append(this.totalLength);
		sb.append(",");
		sb.append(this.dif_Point_Dis);
		sb.append(",");
		sb.append(this.enter_out_DifPoint_Link);
		sb.append(",");
		sb.append(this.dif_Point_Id);
		sb.append(",");
		sb.append(this.dif_lon);
		sb.append(",");
		sb.append(this.dif_lat);
		sb.append(",");
		sb.append(this.difPoint_angle);
		sb.append(",");
		sb.append(this.flag);
		sb.append(",");
		sb.append(this.dir);
		sb.append(",");
		sb.append(this.roadGeo);
		sb.append(",");
		sb.append(this.straight_angle);
		sb.append(",");
		sb.append(this.meshIdSeq);
		sb.append(",");
		sb.append(this.inlaneNoSeq);
		sb.append(",");
		sb.append(this.outlaneNoSeq);
		sb.append(",");
		// 分歧点距离 同一方向（都是左入或左出等等）但是有分叉的公共link的最末尾的距离
		sb.append(this.difPoint_startDis - this.minSuitableDisFromLastLink);
		sb.append(",");
		// 分歧点距离 同一方向（都是左入或左出等等）但是有分叉的公共link的最末尾的距离
		sb.append(this.linksLen);

		return sb.toString();
	}
	public String toString3() {
		StringBuffer sb = new StringBuffer();
		sb.append(this.roadId);
		sb.append(",");
		sb.append(this.linkArr);
//		sb.append(",");
//		sb.append(this.LinkDisArr);
		sb.append(",");
		sb.append(this.totalLength);
		sb.append(",");
		sb.append(this.dif_Point_Dis);
		sb.append(",");
		sb.append(this.enter_out_DifPoint_Link);
		sb.append(",");
		sb.append(this.dif_Point_Id);
		sb.append(",");
		sb.append(this.dif_lon);
		sb.append(",");
		sb.append(this.dif_lat);
		sb.append(",");
		sb.append(this.difPoint_angle);
		sb.append(",");
		sb.append(this.flag);
		sb.append(",");
		sb.append(this.dir);
//		sb.append(",");
//		sb.append(this.roadGeo);
		sb.append(",");
		sb.append(this.straight_angle);
//		sb.append(",");
//		sb.append(this.meshIdSeq);
//		sb.append(",");
//		sb.append(this.inlaneNoSeq);
//		sb.append(",");
//		sb.append(this.outlaneNoSeq);
		sb.append(",");
		// 分歧点距离 同一方向（都是左入或左出等等）但是有分叉的公共link的最末尾的距离
		sb.append(this.difPoint_startDis - this.minSuitableDisFromLastLink);
		sb.append(",");
		// 分歧点距离 同一方向（都是左入或左出等等）但是有分叉的公共link的最末尾的距离
		sb.append(this.linksLen);

		return sb.toString();
	}
	public static DifPointTotalMapInfo parseData1(String line) throws ParseException {
		String[] lineArr = line.split(",");
//		if (line.contains("641764")) {
//			System.out.println(line);
//		}
		if (lineArr.length > 16) {
			DifPointTotalMapInfo difPointTotalMapInfo = new DifPointTotalMapInfo();
			difPointTotalMapInfo.roadId = lineArr[0];
			difPointTotalMapInfo.linkArr = lineArr[1];
			difPointTotalMapInfo.LinkDisArr = lineArr[2];
			difPointTotalMapInfo.totalLength = Integer.parseInt(lineArr[3]);
			difPointTotalMapInfo.dif_Point_Dis = Integer.parseInt(lineArr[4]);
			difPointTotalMapInfo.enter_out_DifPoint_Link = lineArr[5];
			difPointTotalMapInfo.dif_Point_Id = lineArr[6];
			difPointTotalMapInfo.dif_lon = Double.parseDouble(lineArr[7]);
			difPointTotalMapInfo.dif_lat = Double.parseDouble(lineArr[8]);
			difPointTotalMapInfo.difPoint_angle = Double.parseDouble(lineArr[9]);
			difPointTotalMapInfo.flag = Integer.parseInt(lineArr[10]);
			difPointTotalMapInfo.difPoint_startDis = Integer.parseInt(lineArr[11]);
			difPointTotalMapInfo.dir = lineArr[12];
			difPointTotalMapInfo.linksLen = lineArr[13];
			difPointTotalMapInfo.straight_angle = Double.parseDouble(lineArr[14]);
			difPointTotalMapInfo.meshIdSeq = lineArr[15];
			difPointTotalMapInfo.minSuitableDisFromLastLink = Integer.parseInt(lineArr[16]);
			difPointTotalMapInfo.maxSuitableDisFromLastLink = Integer.parseInt(lineArr[17]);
			difPointTotalMapInfo.samelinkLen = Integer.parseInt(lineArr[18]);
			difPointTotalMapInfo.enter_Azimuth = Double.parseDouble(lineArr[19]);
			difPointTotalMapInfo.out_Azimuth = Double.parseDouble(lineArr[20]);
			difPointTotalMapInfo.roadClass = Integer.parseInt(lineArr[21]);
			difPointTotalMapInfo.inlaneNoSeq = lineArr[22];
			difPointTotalMapInfo.outlaneNoSeq = lineArr[23];
			difPointTotalMapInfo.inlinkNum = Integer.parseInt(lineArr[24]);
			difPointTotalMapInfo.outlinkNum = Integer.parseInt(lineArr[25]);
			difPointTotalMapInfo.inlaneTurnFlag = lineArr[26];
			difPointTotalMapInfo.outlaneTurnFlag =lineArr[27];
			difPointTotalMapInfo.difPointFromSamelinkLen = difPointTotalMapInfo.difPoint_startDis - difPointTotalMapInfo.minSuitableDisFromLastLink;

			if (difPointTotalMapInfo.difPointFromSamelinkLen <= 0) {
				return null;
			}
			difPointTotalMapInfo.roadGeo = getGeo1(lineArr);
			return difPointTotalMapInfo;
		}
		return null;
	}

	public static DifPointTotalMapInfo parseData2(String line) throws ParseException {
		String[] lineArr = line.split(",");

		if (lineArr.length > 16) {
			DifPointTotalMapInfo difPointTotalMapInfo = new DifPointTotalMapInfo();
			difPointTotalMapInfo.roadId = lineArr[0];
			difPointTotalMapInfo.linkArr = lineArr[1];
			difPointTotalMapInfo.LinkDisArr = lineArr[2];
			difPointTotalMapInfo.totalLength = Integer.parseInt(lineArr[3]);
			difPointTotalMapInfo.dif_Point_Dis = Integer.parseInt(lineArr[4]);
			difPointTotalMapInfo.enter_out_DifPoint_Link = lineArr[5];
			difPointTotalMapInfo.dif_Point_Id = lineArr[6];
			difPointTotalMapInfo.dif_lon = Double.parseDouble(lineArr[7]);
			difPointTotalMapInfo.dif_lat = Double.parseDouble(lineArr[8]);
			difPointTotalMapInfo.difPoint_angle = Double.parseDouble(lineArr[9]);
			difPointTotalMapInfo.flag = Integer.parseInt(lineArr[10]);
			difPointTotalMapInfo.difPoint_startDis = Integer.parseInt(lineArr[11]);
			difPointTotalMapInfo.dir = lineArr[12];
			difPointTotalMapInfo.linksLen = lineArr[13];
			difPointTotalMapInfo.straight_angle = Double.parseDouble(lineArr[14]);
			difPointTotalMapInfo.meshIdSeq = lineArr[15];
			difPointTotalMapInfo.minSuitableDisFromLastLink = Integer.parseInt(lineArr[16]);
			difPointTotalMapInfo.maxSuitableDisFromLastLink = Integer.parseInt(lineArr[17]);
			difPointTotalMapInfo.samelinkLen = Integer.parseInt(lineArr[18]);
			difPointTotalMapInfo.enter_Azimuth = Double.parseDouble(lineArr[19]);
			difPointTotalMapInfo.out_Azimuth = Double.parseDouble(lineArr[20]);
			difPointTotalMapInfo.roadClass = Integer.parseInt(lineArr[21]);
			difPointTotalMapInfo.difPointFromSamelinkLen = difPointTotalMapInfo.difPoint_startDis - difPointTotalMapInfo.minSuitableDisFromLastLink;

			if (difPointTotalMapInfo.difPointFromSamelinkLen <= 0) {
				return null;
			}
			difPointTotalMapInfo.roadGeo = getGeo2(lineArr);
			return difPointTotalMapInfo;
		}
		return null;
	}

	public static DifPointTotalMapInfo parseData(String line) throws ParseException {

		String[] lineArr = line.split(",");

		if (lineArr.length > 14) {
			DifPointTotalMapInfo difPointTotalMapInfo = new DifPointTotalMapInfo();
			difPointTotalMapInfo.roadId = lineArr[0];
			difPointTotalMapInfo.linkArr = lineArr[1];
			difPointTotalMapInfo.LinkDisArr = lineArr[2];
			difPointTotalMapInfo.totalLength = Integer.parseInt(lineArr[3]);
			difPointTotalMapInfo.dif_Point_Dis = Integer.parseInt(lineArr[4]);
			difPointTotalMapInfo.enter_out_DifPoint_Link = lineArr[5];
			difPointTotalMapInfo.dif_Point_Id = lineArr[6];
			difPointTotalMapInfo.dif_lon = Double.parseDouble(lineArr[7]);
			difPointTotalMapInfo.dif_lat = Double.parseDouble(lineArr[8]);
			difPointTotalMapInfo.difPoint_angle = Double.parseDouble(lineArr[9]);
			difPointTotalMapInfo.flag = Integer.parseInt(lineArr[10]);
			difPointTotalMapInfo.difPoint_startDis = Integer.parseInt(lineArr[11]);
			difPointTotalMapInfo.dir = lineArr[12];
			difPointTotalMapInfo.linksLen = lineArr[13];
			difPointTotalMapInfo.straight_angle = Double.parseDouble(lineArr[14]);
			difPointTotalMapInfo.meshIdSeq = lineArr[15];
			difPointTotalMapInfo.roadGeo = getGeo(lineArr);
			return difPointTotalMapInfo;
		}
		return null;
	}

	public String toString1() {
		StringBuffer sb = new StringBuffer();
		sb.append(this.roadId);
		sb.append(",");
		sb.append(this.linkArr);
		sb.append(",");
		sb.append(this.LinkDisArr);
		sb.append(",");
		sb.append(this.totalLength);
		sb.append(",");
		sb.append(this.dif_Point_Dis);
		sb.append(",");
		sb.append(this.enter_out_DifPoint_Link);
		sb.append(",");
		sb.append(this.dif_Point_Id);
		sb.append(",");
		sb.append(this.dif_lon);
		sb.append(",");
		sb.append(this.dif_lat);
		sb.append(",");
		sb.append(this.difPoint_angle);
		sb.append(",");
		sb.append(this.flag);
		sb.append(",");
		sb.append(this.difPoint_startDis);
		sb.append(",");
		sb.append(this.dir);
		sb.append(",");
		sb.append(this.linksLen);
		sb.append(",");
		sb.append(this.straight_angle);
		sb.append(",");
		sb.append(this.meshIdSeq);
		sb.append(",");
		sb.append(this.minSuitableDisFromLastLink);
		sb.append(",");
		sb.append(this.maxSuitableDisFromLastLink);
		sb.append(",");
		sb.append(this.samelinkLen);
		sb.append(",");
		sb.append(this.enter_Azimuth);
		sb.append(",");
		sb.append(this.out_Azimuth);
		sb.append(",");
		sb.append(this.roadClass);
		sb.append(",");
		sb.append(this.roadGeo.toString());
		return sb.toString();
	}

	public String toString2() {
		StringBuffer sb = new StringBuffer();
		sb.append(this.roadId);
		sb.append(",");
		sb.append(this.linkArr);
		sb.append(",");
		sb.append(this.LinkDisArr);
		sb.append(",");
		sb.append(this.totalLength);
		sb.append(",");
		sb.append(this.dif_Point_Dis);
		sb.append(",");
		sb.append(this.enter_out_DifPoint_Link);
		sb.append(",");
		sb.append(this.dif_Point_Id);
		sb.append(",");
		sb.append(this.dif_lon);
		sb.append(",");
		sb.append(this.dif_lat);
		sb.append(",");
		sb.append(this.difPoint_angle);
		sb.append(",");
		sb.append(this.flag);
		sb.append(",");
		sb.append(this.difPoint_startDis);
		sb.append(",");
		sb.append(this.dir);
		sb.append(",");
		sb.append(this.linksLen);
		sb.append(",");
		sb.append(this.straight_angle);
		sb.append(",");
		sb.append(this.meshIdSeq);
		sb.append(",");
		sb.append(this.minSuitableDisFromLastLink);
		sb.append(",");
		sb.append(this.maxSuitableDisFromLastLink);
		sb.append(",");
		sb.append(this.samelinkLen);
		sb.append(",");
		sb.append(this.enter_Azimuth);
		sb.append(",");
		sb.append(this.out_Azimuth);
		sb.append(",");
		sb.append(this.roadClass);
		sb.append(",");
		sb.append(this.inlaneNoSeq);
		sb.append(",");
		sb.append(this.outlaneNoSeq);
		sb.append(",");
		sb.append(this.inlinkNum);
		sb.append(",");
		sb.append(this.outlinkNum);
		sb.append(",");
		sb.append(this.inlaneTurnFlag);
		sb.append(",");
		sb.append(this.outlaneTurnFlag);
		sb.append(",");
		sb.append(this.roadGeo.toString());
		return sb.toString();
	}

	private static Geometry getGeo(String[] lineArr) throws ParseException {
		// TODO Auto-generated method stub
		// int length = lineArr.length;
		String outLine = "";
		for (int i = 16; i < lineArr.length; i++) {
			outLine += lineArr[i];
			if (i != lineArr.length - 1) {
				outLine += ",";
			}
		}
		Geometry g1 = new WKTReader().read(outLine);
		return g1;
	}

	private static Geometry getGeo1(String[] lineArr) throws ParseException {
		// TODO Auto-generated method stub
		// int length = lineArr.length;
		String outLine = "";
		for (int i = 28; i < lineArr.length; i++) {
			outLine += lineArr[i];
			if (i != lineArr.length - 1) {
				outLine += ",";
			}
		}
		Geometry g1 = new WKTReader().read(outLine);
		return g1;
	}

	private static Geometry getGeo2(String[] lineArr) throws ParseException {
		// TODO Auto-generated method stub
		// int length = lineArr.length;
		String outLine = "";
		for (int i = 22; i < lineArr.length; i++) {
			outLine += lineArr[i];
			if (i != lineArr.length - 1) {
				outLine += ",";
			}
		}
		Geometry g1 = new WKTReader().read(outLine);
		return g1;
	}

	public static void main(String[] args) throws ParseException, IOException {
		String line = "7720725_7726933,7720725|7726933,0|105,346,105,7720725|7726933,5221361,121.37669,31.11792,100.0,2,241,01,7720725:105|7726933:241,100.0,466153_0_19|466153_1_19,0,346,346,88.2703316791293,100.36793420430847,POLYGON ((121.37669653036447 31.118020203346674, 121.37822740347313 31.11805996628456, 121.37823128194593 31.118059991782737, 121.37901064099938 31.11805, 121.37922 31.11805, 121.3792395090322 31.11804807852804, 121.37925826834324 31.118042387953253, 121.3792755570233 31.11803314696123, 121.37929071067812 31.11802071067812, 121.37930314696123 31.118005557023302, 121.37931238795325 31.117988268343236, 121.37931807852804 31.117969509032203, 121.37932 31.11795, 121.37931807852804 31.117930490967797, 121.37931238795325 31.117911731656765, 121.37930314696123 31.1178944429767, 121.37929071067812 31.11787928932188, 121.3792755570233 31.11786685303877, 121.37925826834324 31.11785761204675, 121.3792395090322 31.11785192147196, 121.37922 31.11785, 121.37901 31.11785, 121.37900871805407 31.117850008217264, 121.37823065753777 31.117859983352087, 121.37669259652687 31.117820033715443, 121.37667445071364 31.11782121629844, 121.37559445071363 31.11799121629844, 121.37557547774468 31.117996147914848, 121.37555783144661 31.118004686214256, 121.3755421899568 31.118016503074607, 121.37552915436892 31.11803114438058, 121.37551922563331 31.118048047475003, 121.3755127853057 31.118066562781433, 121.37551008088428 31.11808597876703, 121.37551121629843 31.118105549286355, 121.37551614791484 31.118124522255325, 121.37552468621425 31.118142168553383, 121.3755365030746 31.11815781004319, 121.37555114438058 31.118170845631067, 121.375568047475 31.11818077436668, 121.37558656278144 31.118187214694288, 121.37560597876703 31.118189919115714, 121.37562554928635 31.11818878370156, 121.37669653036447 31.118020203346674))";
		DifPointTotalMapInfo difPointTotalMapInfo = new DifPointTotalMapInfo().parseData1(line);
		System.out.println(difPointTotalMapInfo.enter_Azimuth);
	}
}
